using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;

namespace Janus.NorthwindDemo2007
{
	public class OrdersDataProvider : DataProvider
	{

		internal Janus.NorthwindDemo2007.NorthwindDataTableAdapters.OrdersTableAdapter OrdersTableAdapter1;
		internal Janus.NorthwindDemo2007.NorthwindDataTableAdapters.Order_DetailsTableAdapter OrderDetailsTableAdapter1;
        internal Janus.NorthwindDemo2007.NorthwindDataTableAdapters.Product_CategoriesTableAdapter productCategoriesAdapter;
		public OrdersDataProvider() : base()
		{
			this.OrdersTableAdapter1 = new Janus.NorthwindDemo2007.NorthwindDataTableAdapters.OrdersTableAdapter();
			this.OrderDetailsTableAdapter1 = new Janus.NorthwindDemo2007.NorthwindDataTableAdapters.Order_DetailsTableAdapter();
            this.productCategoriesAdapter = new Janus.NorthwindDemo2007.NorthwindDataTableAdapters.Product_CategoriesTableAdapter();
			this.DataAdapter = this.OrdersTableAdapter1.DataAdapter;
			this.OrderDetailsTableAdapter1.DataAdapter.RowUpdated += new System.Data.OleDb.OleDbRowUpdatedEventHandler(this.DetailsAdapter_RowUpdated);
		}

		protected override bool FillCore()
		{
			this.OrdersTableAdapter1.Fill(this.DataSet.Orders);
			if (this.IncludeDetails)
			{
				this.LoadOrderDetails();
			}
			return true;
		}
		protected override bool UpdateCore()
		{
			this.OrdersTableAdapter1.Update(this.DataSet.Orders);
			if (mIncludeDetails)
			{
				if (! this.UpdateOrderDetails())
				{
					return false;
				}
			}
			return true;
		}
		private bool UpdateOrderDetails()
		{
			this.OrderDetailsTableAdapter1.Update(this.DataSet.Order_Details);
			return true;
		}
		protected override bool UpdateDataRowCore(System.Data.DataRow row)
		{
			this.OrdersTableAdapter1.Update(row);
			NorthwindData ds = null;


			ds = (NorthwindData)row.Table.DataSet;

			DataTable changes = ds.Order_Details.GetChanges();
			if (changes != null)
			{
				if (mDetailsLoaded)
				{
					foreach (DataRow detail in changes.Rows)
					{
						if (detail.RowState == DataRowState.Deleted)
						{
							if (detail.HasVersion(DataRowVersion.Original))
							{
								//find the row in the loaded data and delete from the dataset too.
								DataRow drToDelete = this.DataSet.Order_Details.FindByOrderIDProductID((int)detail["OrderId", DataRowVersion.Original], (int)detail["ProductId", DataRowVersion.Original]);
								drToDelete.Delete();
								drToDelete.AcceptChanges();
							}
						}
						else
						{
							this.DataSet.Order_Details.LoadDataRow(detail.ItemArray, true);
						}
					}
				}
				this.OrderDetailsTableAdapter1.Update((NorthwindData.Order_DetailsDataTable)changes);

			}
			return true;
		}


		private bool mDetailsLoaded;
		private bool mIncludeDetails;
		public bool IncludeDetails
		{
			get
			{
				return mIncludeDetails;
			}
			set
			{
				if (mIncludeDetails != value)
				{
					mIncludeDetails = value;
					if (this.mDataLoaded)
					{
						if (mIncludeDetails)
						{
							LoadOrderDetails();
						}
						else
						{
							//update data before clearing details
							if (! this.Update())
							{
								return;
							}
							//clear order details table
							this.DataSet.Order_Details.Clear();
							mDetailsLoaded = false;
						}
					}
				}
			}
		}
		private void LoadOrderDetails()
		{
			this.DataSet.EnforceConstraints = false;
			this.OrderDetailsTableAdapter1.Fill(this.DataSet.Order_Details);
            this.productCategoriesAdapter.Fill(this.DataSet.Product_Categories);
			mDetailsLoaded = true;
			this.DataSet.EnforceConstraints = true;
		}

		private void DetailsAdapter_RowUpdated(object sender, System.Data.OleDb.OleDbRowUpdatedEventArgs e)
		{
			if (e.Status != UpdateStatus.ErrorsOccurred)
			{
				e.Row.AcceptChanges();
			}
			else
			{
				e.Row.RejectChanges();
			}
		}

		protected override void OnRowUpdated(System.Data.OleDb.OleDbRowUpdatedEventArgs e)
		{
			//this is done with tables that have autonumber fields
			if (e.Status != UpdateStatus.ErrorsOccurred)
			{

				// Include a variable and a command to retrieve the identity value from the Access database.
				int newID = 0;
				System.Data.OleDb.OleDbCommand idCMD = null;

				if (e.StatementType == StatementType.Insert)
				{
					idCMD = new System.Data.OleDb.OleDbCommand("SELECT @@IDENTITY", this.OrdersTableAdapter1.Connection);
					// Retrieve the identity value and store it in the CategoryID column.
					newID = System.Convert.ToInt32(idCMD.ExecuteScalar());
					e.Row["OrderID"] = newID;
					idCMD.Dispose();
				}

			}
			base.OnRowUpdated(e);
		}


	}

} //end of root namespace